#include "StdAfx.h"
#include "Input.h"
#include "Helper.h"

IDirectInput8 *Input::sm_pDirectInput = NULL;
IDirectInputDevice8 *Input::sm_pKeyboard = NULL;
IDirectInputDevice8 *Input::sm_pMouse = NULL;
DIMOUSESTATE Input::sm_MouseState;
char Input::sm_keyBuffer[256];

bool Input::Initialize(HWND hWnd, HINSTANCE hInstance, DWORD dwKeyboardCooperative, DWORD dwMouseCooperative)
{
	bool success = false;
	
	sm_pDirectInput = NULL;
	sm_pKeyboard = NULL;
	sm_pMouse = NULL;
	ZeroMemory(sm_keyBuffer, sizeof(char) * 256);
	ZeroMemory(&sm_MouseState, sizeof(sm_MouseState));

	DEFINE_HR;

	do 
	{
		HR_BREAK(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&sm_pDirectInput, NULL));

		HR_BREAK(sm_pDirectInput->CreateDevice(GUID_SysKeyboard, &sm_pKeyboard, NULL ));
		HR_BREAK(sm_pKeyboard->SetCooperativeLevel(hWnd, dwKeyboardCooperative));
		HR_BREAK(sm_pKeyboard->SetDataFormat(&c_dfDIKeyboard));
		HR_BREAK(sm_pKeyboard->Acquire());
		HR_BREAK(sm_pKeyboard->Poll());

		HR_BREAK(sm_pDirectInput->CreateDevice(GUID_SysMouse, &sm_pMouse, NULL));
		HR_BREAK(sm_pMouse->SetCooperativeLevel(hWnd, dwMouseCooperative));
		HR_BREAK(sm_pMouse->SetDataFormat(&c_dfDIMouse));
		HR_BREAK(sm_pMouse->Acquire());
		HR_BREAK(sm_pMouse->Poll());

		success = true;
	} while (0);

	return success;
}

void Input::Release()
{
	if (sm_pKeyboard != NULL)
	{
		sm_pKeyboard->Unacquire();
		sm_pKeyboard->Release();
		sm_pKeyboard = NULL;
	}

	if (sm_pMouse != NULL)
	{
		sm_pMouse->Unacquire();
		sm_pMouse->Release();
		sm_pMouse = NULL;
	}

	if (sm_pDirectInput != NULL)
	{
		sm_pDirectInput->Release();
		sm_pDirectInput = NULL;
	}
}

void Input::Update()
{
	HRESULT hr = S_FALSE;

	if (sm_pKeyboard != NULL)
	{
		hr = sm_pKeyboard->GetDeviceState(sizeof(sm_keyBuffer), (void**)&sm_keyBuffer); 

		if(FAILED(hr))
		{
			sm_pKeyboard->Acquire();  
			sm_pKeyboard->GetDeviceState(sizeof(sm_keyBuffer),(LPVOID)sm_keyBuffer);
		}
	}

	if (sm_pMouse != NULL)
	{
		hr = sm_pMouse->GetDeviceState(sizeof(DIMOUSESTATE), (void**)&sm_MouseState); 

		if(FAILED(hr))
		{
			sm_pMouse->Acquire();
			sm_pMouse->GetDeviceState(sizeof(DIMOUSESTATE), (void**)&sm_MouseState);
		}
	}
}

long Input::GetAxisRaw(Orientation eOrient)
{
	switch (eOrient)
	{
	case MouseY:
		return sm_MouseState.lY;
	case MouseX:
		return sm_MouseState.lX;
	case MouseZ:
		return sm_MouseState.lZ;
	}

	return 0;
}

bool Input::GetKeyDown(int nKey)
{
	return (sm_keyBuffer[nKey] & 0x80) != 0;
}

bool Input::GetButtonDown(int nButton)
{
	return (sm_MouseState.rgbButtons[nButton] & 0x80) != 0;
}
